#include "main.h"
#include "OLED.h"
#include "OLED_Data.h"


//#define OLED0561_ADD	0x78  //OLED的I2C地址
//#define COM				0x00  //OLED 指令
//#define DAT 			0x40  //OLED 数据

void OLED_WriteCommand(uint8_t SPI_Command)//写命令
{
	OLED_DC_Clr();
	OLED_CS_Clr();
	HAL_SPI_Transmit(&hspi1,&SPI_Command,1,1000);
	OLED_CS_Set();	  
	OLED_DC_Set();
	
}
		
void OLED_WriteData(uint8_t SPI_Data)//写数据
{
	OLED_DC_Set();
	
	OLED_CS_Clr();
	HAL_SPI_Transmit(&hspi1,&SPI_Data,1,1000);
	OLED_CS_Set();	  
	OLED_DC_Set();
	
}

/**
  * @brief  OLED设置光标位置
  * @param  Y 以左上角为原点，向下方向的坐标，范围：0~7
  * @param  X 以左上角为原点，向右方向的坐标，范围：0~127
  * @retval 无
  */
void OLED_SetCursor(uint8_t Y, uint8_t X)
{
	OLED_WriteCommand(0xB0 | Y);					//设置Y位置
	OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4));	//设置X位置高4位
	OLED_WriteCommand(0x00 | (X & 0x0F));			//设置X位置低4位
}

/**
  * @brief  OLED清屏
  * @param  无
  * @retval 无
  */
void OLED_Clear(void)
{
	
	uint8_t i, j;
	for (j = 0; j < 8; j++)
	{
		OLED_SetCursor(j, 0);
		for(i = 0; i < 128; i++)
		{
			OLED_WriteData(0x00);
		}
	}

}

/**
  * @brief  OLED显示一个字符
  * @param  Line 行位置，范围：1~4
  * @param  Column 列位置，范围：1~16
  * @param  Char 要显示的一个字符，范围：ASCII可见字符
  * @retval 无
  */
void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char)
{      	
	uint8_t i;
	OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8);		//设置光标位置在上半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(OLED_F8x16[Char - ' '][i]);			//显示上半部分内容
	}
	OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8);	//设置光标位置在下半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(OLED_F8x16[Char - ' '][i + 8]);		//显示下半部分内容
	}
}
void OLED_ShowSmallChar(uint8_t Line, uint8_t Column, uint8_t num)
{      	
	uint8_t i;
	OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8);		//设置光标位置在上半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(OLED_SmallNum[num][i]);			//显示上半部分内容
	}
	OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8);	//设置光标位置在下半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(OLED_SmallNum[num][i + 8]);		//显示下半部分内容
	}
}
void OLED_ShowLocation(uint8_t Line, uint8_t Column, bool sign)
{   
	uint8_t i;
	if(sign==1){
		
		OLED_SetCursor((Line - 1) * 2, (Column - 1) * 16);		//设置光标位置在上半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(LocationBmp[i]);			//显示上半部分内容
		}
		OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 16);	//设置光标位置在下半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(LocationBmp[i + 16]);		//显示下半部分内容
		}
	}else{
		OLED_SetCursor((Line - 1) * 2, (Column - 1) * 16);		//设置光标位置在上半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(LocationError[i]);			//显示上半部分内容
		}
		OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 16);	//设置光标位置在下半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(LocationError[i + 16]);		//显示下半部分内容
		}
	}
}

void OLED_ShowHeart(uint8_t Line, uint8_t Column, bool sign)
{
	uint8_t i;
	if(sign==1){
		
		OLED_SetCursor((Line - 1) * 2, (Column - 1) * 16);		//设置光标位置在上半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(HeartLarge[i]);			//显示上半部分内容
		}
		OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 16);	//设置光标位置在下半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(HeartLarge[i + 16]);		//显示下半部分内容
		}
	}else{
		OLED_SetCursor((Line - 1) * 2, (Column - 1) * 16);		//设置光标位置在上半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(HeartSmall[i]);			//显示上半部分内容
		}
		OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 16);	//设置光标位置在下半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(HeartSmall[i + 16]);		//显示下半部分内容
		}
	}
	
}

void OLED_ShowExercise(uint8_t Line, uint8_t Column, uint8_t sign)
{
	uint8_t i;
	if(sign==Running){
		
		OLED_SetCursor((Line - 1) * 2, (Column - 1) * 16);		//设置光标位置在上半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(RunBmp[i]);			//显示上半部分内容
		}
		OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 16);	//设置光标位置在下半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(RunBmp[i + 16]);		//显示下半部分内容
		}
	}else if(sign==Cycling){
		OLED_SetCursor((Line - 1) * 2, (Column - 1) * 16);		//设置光标位置在上半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(CyclingBmp[i]);			//显示上半部分内容
		}
		OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 16);	//设置光标位置在下半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(CyclingBmp[i + 16]);		//显示下半部分内容
		}
	}else if(sign==Swimming){
		OLED_SetCursor((Line - 1) * 2, (Column - 1) * 16);		//设置光标位置在上半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(SwimmingBmp[i]);			//显示上半部分内容
		}
		OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 16);	//设置光标位置在下半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(SwimmingBmp[i + 16]);		//显示下半部分内容
		}
	}else if(sign==Walking){
		OLED_SetCursor((Line - 1) * 2, (Column - 1) * 16);		//设置光标位置在上半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(WalkBmp[i]);			//显示上半部分内容
		}
		OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 16);	//设置光标位置在下半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(WalkBmp[i + 16]);		//显示下半部分内容
		}
	}else if(sign==Fitness){
		OLED_SetCursor((Line - 1) * 2, (Column - 1) * 16);		//设置光标位置在上半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(FitnessBmp[i]);			//显示上半部分内容
		}
		OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 16);	//设置光标位置在下半部分
		for (i = 0; i < 16; i++)
		{
			OLED_WriteData(FitnessBmp[i + 16]);		//显示下半部分内容
		}
	}
	
	
}

void OLED_ShowStepsOrKcal(uint8_t Line, uint8_t Column, bool sign)
{
	uint8_t i;
	if(sign==1){
		OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8);		//设置光标位置在上半部分
		for (i = 0; i < 8; i++)
		{
			OLED_WriteData(StepBmp[i]);			//显示上半部分内容
		}
		OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8);	//设置光标位置在下半部分
		for (i = 0; i < 8; i++)
		{
			OLED_WriteData(StepBmp[i + 8]);		//显示下半部分内容
		}
	}else{
		OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8);		//设置光标位置在上半部分
		for (i = 0; i < 8; i++)
		{
			OLED_WriteData(KcalBmp[i]);			//显示上半部分内容
		}
		OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8);	//设置光标位置在下半部分
		for (i = 0; i < 8; i++)
		{
			OLED_WriteData(KcalBmp[i + 8]);		//显示下半部分内容
		}
	}
	
}

void OLED_ShowSpO2(uint8_t Line, uint8_t Column)
{
	uint8_t i;
	OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8);		//设置光标位置在上半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(SpO2Bmp[i]);			//显示上半部分内容
	}
	OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8);	//设置光标位置在下半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(SpO2Bmp[i + 8]);		//显示下半部分内容
	}
	
}

void OLED_ShowSleepLight(uint8_t Line, uint8_t Column)
{
	uint8_t i;
	OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8);		//设置光标位置在上半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(SleepLightBmp[i]);			//显示上半部分内容
	}
	OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8);	//设置光标位置在下半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(SleepLightBmp[i + 8]);		//显示下半部分内容
	}
	
}

void OLED_ShowSleepDeep(uint8_t Line, uint8_t Column)
{
	uint8_t i;
	OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8);		//设置光标位置在上半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(SleepDeepBmp[i]);			//显示上半部分内容
	}
	OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8);	//设置光标位置在下半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(SleepDeepBmp[i + 8]);		//显示下半部分内容
	}
	
}

void OLED_ShowAwake(uint8_t Line, uint8_t Column)
{
	uint8_t i;
	OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8);		//设置光标位置在上半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(AwakeBmp[i]);			//显示上半部分内容
	}
	OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8);	//设置光标位置在下半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(AwakeBmp[i + 8]);		//显示下半部分内容
	}
	
}


void OLED_ShowColon(uint8_t Line, uint8_t Column)
{      	
	uint8_t i;
	// 显示第一部分内容
	OLED_SetCursor((Line - 1) * 4, (Column - 1) * 16);		//设置光标位置在第一部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(ColonBmp[i]);			    //显示第一部分内容
	}
	// 显示第二部分内容
	OLED_SetCursor((Line - 1) * 4 + 1, (Column - 1) * 16);	//设置光标位置在第二部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(ColonBmp[i + 16]);		    //显示第二部分内容
	}
	// 显示第三部分内容
	OLED_SetCursor((Line - 1) * 4 + 2, (Column - 1) * 16);	//设置光标位置在第三部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(ColonBmp[i + 32]);			//显示第三部分内容
	}
	// 显示第四部分内容
	OLED_SetCursor((Line - 1) * 4 + 3, (Column - 1) * 16);	//设置光标位置在第四部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(ColonBmp[i + 48]);			//显示第四部分内容
	}

}



/**
  * @brief  OLED显示一个16*32字符
  * @param  Line 行位置，范围：1~2
  * @param  Column 列位置，范围：1~8
  * @param  Char 要显示的一个字符，范围：ASCII可见字符
  * @retval 无
  */
void OLED_ShowLargeChar(uint8_t Line, uint8_t Column, uint8_t num)
{      	
	uint8_t i;
	// 显示第一部分内容
	OLED_SetCursor((Line - 1) * 4, (Column - 1) * 16);		//设置光标位置在第一部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(OLED_F16x32NUM[num][i]);			    //显示第一部分内容
	}
	// 显示第二部分内容
	OLED_SetCursor((Line - 1) * 4 + 1, (Column - 1) * 16);	//设置光标位置在第二部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(OLED_F16x32NUM[num][i + 16]);		    //显示第二部分内容
	}
	// 显示第三部分内容
	OLED_SetCursor((Line - 1) * 4 + 2, (Column - 1) * 16);	//设置光标位置在第三部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(OLED_F16x32NUM[num][i + 32]);			//显示第三部分内容
	}
	// 显示第四部分内容
	OLED_SetCursor((Line - 1) * 4 + 3, (Column - 1) * 16);	//设置光标位置在第四部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(OLED_F16x32NUM[num][i + 48]);			//显示第四部分内容
	}
}

void OLED_ShowSleep(uint8_t Line, uint8_t Column)
{
	uint8_t i;
	// 显示第一部分内容
	OLED_SetCursor((Line - 1) * 4, (Column - 1) * 16);		//设置光标位置在第一部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(SleepBmp[i]);			    //显示第一部分内容
	}
	// 显示第二部分内容
	OLED_SetCursor((Line - 1) * 4 + 1, (Column - 1) * 16);	//设置光标位置在第二部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(SleepBmp[i + 16]);		    //显示第二部分内容
	}
	// 显示第三部分内容
	OLED_SetCursor((Line - 1) * 4 + 2, (Column - 1) * 16);	//设置光标位置在第三部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(SleepBmp[i + 32]);			//显示第三部分内容
	}
	// 显示第四部分内容
	OLED_SetCursor((Line - 1) * 4 + 3, (Column - 1) * 16);	//设置光标位置在第四部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(SleepBmp[i + 48]);			//显示第四部分内容
	}
}
/**
  * @brief  OLED显示字符串
  * @param  Line 起始行位置，范围：1~4
  * @param  Column 起始列位置，范围：1~16
  * @param  String 要显示的字符串，范围：ASCII可见字符
  * @retval 无
  */
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String)
{
	uint8_t i;
	for (i = 0; String[i] != '\0'; i++)
	{
		OLED_ShowChar(Line, Column + i, String[i]);
	}
}

/**
  * @brief  OLED次方函数
  * @retval 返回值等于X的Y次方
  */
uint32_t OLED_Pow(uint32_t X, uint32_t Y)
{
	uint32_t Result = 1;
	while (Y--)
	{
		Result *= X;
	}
	return Result;
}

/**
  * @brief  OLED显示固定长度的数字（十进制，正数）
  * @param  Line 起始行位置，范围：1~4
  * @param  Column 起始列位置，范围：1~16
  * @param  Number 要显示的数字，范围：0~4294967295
  * @param  Length 要显示数字的长度，范围：1~10
  * @retval 无
  */
void OLED_ShowFixedLengthNumber(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0');
	}

}

/**
 * @brief 在 OLED 显示屏上显示一个无符号整数，并在数字后填充空格以满足最大长度
 * 
 * 这个函数将一个无符号整数以指定的格式显示在 OLED 屏幕上。如果数字的位数小于 `maxLength`，函数会
 * 在数字后面填充空格以确保总长度达到 `maxLength`。如果数字的位数超过 `maxLength`，函数会截取
 * 数字的末尾部分进行显示。
 * 
 * @param Line            OLED 屏幕上的行号（通常为 0 或 1）
 * @param Column          OLED 屏幕上的列号（显示的起始位置）
 * @param Number          要显示的无符号整数
 * @param maxLength       最大显示长度（包括所有的数字位数和后面的空格）
 */
void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t maxLength)
{
    uint8_t digits[10];  // 用于存储每一位数字
    uint8_t numDigits = 0;  // 记录数字的位数

    // 处理数字0的特殊情况
    if (Number == 0) {
        digits[numDigits++] = 0;
    } else {
        // 将数字的每一位存入digits数组中，倒序存储
        while (Number > 0) {
            digits[numDigits++] = Number % 10;
            Number /= 10;
        }
    }

    // 计算实际需要显示的数字位数
    uint8_t numToShow = (numDigits > maxLength) ? maxLength : numDigits;

    // 倒序显示digits中的数字
    for (int i = numToShow - 1; i >= 0; i--) {
        OLED_ShowChar(Line, Column + (numToShow - 1 - i), digits[i] + '0');
    }

    // 计算需要填充的空格数量
    uint8_t numSpaces = maxLength - numToShow;

    // 显示后面的空格
    for (uint8_t i = 0; i < numSpaces; i++) {
        OLED_ShowChar(Line, Column + numToShow + i, ' ');
    }
}

/**
  * @brief  OLED显示数字（大）（十进制，正数）
  * @param  Line 起始行位置，范围：1~2
  * @param  Column 起始列位置，范围：1~8
  * @param  Number 要显示的数字，范围：0~4294967295
  * @param  Length 要显示数字的长度，范围：1~9
  * @retval 无
  */
void OLED_ShowLargeNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowLargeChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + 0);
	}
}
void OLED_ShowSmallNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowSmallChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + 0);
	}

}
/**
  * @brief  OLED显示数字（十进制，带符号数）
  * @param  Line 起始行位置，范围：1~4
  * @param  Column 起始列位置，范围：1~16
  * @param  Number 要显示的数字，范围：-2147483648~2147483647
  * @param  Length 要显示数字的长度，范围：1~10
  * @retval 无
  */
void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length) {
    uint8_t i;
    uint32_t Number1;
    int32_t absNumber = (Number >= 0) ? Number : -Number;
    uint8_t numDigits = 0;

    // 计算数字的位数（不包括符号）
    if (absNumber == 0) {
        numDigits = 1; // 特殊情况：数字为0
    } else {
        while (absNumber > 0) {
            absNumber /= 10;
            numDigits++;
        }
    }

    // 计算需要填充的空格数量
    uint8_t padding = Length - numDigits - 1;
    
    // 显示前导空格
    for (i = 0; i < padding; i++) {
        OLED_ShowChar(Line, Column + i, ' ');
    }

    // 更新列位置以跳过前导空格
    Column += padding;

    // 显示符号（如果有）
    if (Number < 0) {
        OLED_ShowChar(Line, Column, '-');
        Number1 = -Number;  // 取绝对值进行下面的处理
        Column++;
    } else {
        Number1 = Number;   // 正数直接使用
        OLED_ShowChar(Line, Column, ' '); // 如果需要，可以填充1个空格来对齐
        Column++;
    }

    // 显示数字
    for (i = 0; i < numDigits; i++) {
        OLED_ShowChar(Line, Column + i, (Number1 / OLED_Pow(10, numDigits - i - 1)) % 10 + '0');
    }
}
/**
  * @brief  OLED显示数字（十六进制，正数）
  * @param  Line 起始行位置，范围：1~4
  * @param  Column 起始列位置，范围：1~16
  * @param  Number 要显示的数字，范围：0~0xFFFFFFFF
  * @param  Length 要显示数字的长度，范围：1~8
  * @retval 无
  */
void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i, SingleNumber;
	for (i = 0; i < Length; i++)							
	{
		SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16;
		if (SingleNumber < 10)
		{
			OLED_ShowChar(Line, Column + i, SingleNumber + '0');
		}
		else
		{
			OLED_ShowChar(Line, Column + i, SingleNumber - 10 + 'A');
		}
	}
}

/**
  * @brief  OLED显示数字（二进制，正数）
  * @param  Line 起始行位置，范围：1~4
  * @param  Column 起始列位置，范围：1~16
  * @param  Number 要显示的数字，范围：0~1111 1111 1111 1111
  * @param  Length 要显示数字的长度，范围：1~16
  * @retval 无
  */
void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + '0');
	}
}

/**
 * @brief 在 OLED 显示屏上显示浮点数
 * 
 * 这个函数将一个浮点数以指定的格式显示在 OLED 屏幕上的指定位置。它支持自定义显示小数位数和总长度。
 * 
 * @param Line            OLED 屏幕上的行号（通常为 0 或 1）
 * @param Column          OLED 屏幕上的列号（显示的起始位置）
 * @param Number          要显示的浮点数
 * @param maxLength       最大显示长度（包括整数部分、小数点、小数部分）
 * @param decimalPlaces   小数部分显示的位数
 * 
 * 该函数将浮点数分解为整数部分和小数部分，并按照给定的格式在 OLED 屏幕上显示。如果总长度超过最大长度，
 * 函数会自动减少小数位数以适应显示区域。
 */
void OLED_ShowFloat(uint8_t Line, uint8_t Column, float Number, uint8_t maxLength, uint8_t decimalPlaces)
{
    uint8_t digits[10];  // 用于存储每一位数字
    uint8_t numDigits = 0;  // 记录整数部分的位数
    int32_t integerPart = (int32_t)Number;  // 整数部分
    float fractionalPart = Number - (float)integerPart;  // 小数部分

    // 处理整数部分
    if (integerPart == 0) {
        digits[numDigits++] = 0;
    } else {
        while (integerPart > 0) {
            digits[numDigits++] = integerPart % 10;
            integerPart /= 10;
        }
    }

    // 计算实际显示的位数
    uint8_t totalLength = numDigits + decimalPlaces + 1; // 总长度 = 整数位数 + 小数位数 + 小数点位数
    if (totalLength > maxLength) {
        decimalPlaces -= (totalLength - maxLength);  // 如果总长度超过最大长度，减少小数位数
    }

    // 倒序显示整数部分的数字
    for (int i = numDigits - 1; i >= 0; i--) {
        OLED_ShowChar(Line, Column, digits[i] + '0');
        Column++;  // 每个字符后移动一列
    }

    // 显示小数点
    if (decimalPlaces > 0) {
        OLED_ShowChar(Line, Column, '.');
        Column++;
    }

    // 处理小数部分
    for (uint8_t i = 0; i < decimalPlaces; i++) {
        fractionalPart *= 10;
        uint8_t digit = (uint8_t)fractionalPart;
        OLED_ShowChar(Line, Column, digit + '0');
        fractionalPart -= digit;
        Column++;
    }
}
/**
  * @brief  OLED初始化
  * @param  无
  * @retval 无
  */
void OLED_Init(void)
{
	OLED_RES_Set();
	HAL_Delay(100);
	
	OLED_RES_Clr();
	HAL_Delay(100);
	
	OLED_RES_Set();
	HAL_Delay(100);
	
	OLED_WriteCommand(0xAE);	//关闭显示
	
	OLED_WriteCommand(0xD5);	//设置显示时钟分频比/振荡器频率
	OLED_WriteCommand(0x80);
	
	OLED_WriteCommand(0xA8);	//设置多路复用率
	OLED_WriteCommand(0x3F);
	
	OLED_WriteCommand(0xD3);	//设置显示偏移
	OLED_WriteCommand(0x00);
	
	OLED_WriteCommand(0x40);	//设置显示开始行
	
	OLED_WriteCommand(0xA1);	//设置左右方向，0xA1正常 0xA0左右反置
	
	OLED_WriteCommand(0xC8);	//设置上下方向，0xC8正常 0xC0上下反置

	OLED_WriteCommand(0xDA);	//设置COM引脚硬件配置
	OLED_WriteCommand(0x12);
	
	OLED_WriteCommand(0x81);	//设置对比度控制
	OLED_WriteCommand(0xCF);

	OLED_WriteCommand(0xD9);	//设置预充电周期
	OLED_WriteCommand(0xF1);

	OLED_WriteCommand(0xDB);	//设置VCOMH取消选择级别
	OLED_WriteCommand(0x30);

	OLED_WriteCommand(0xA4);	//设置整个显示打开/关闭

	OLED_WriteCommand(0xA6);	//设置正常/倒转显示

	OLED_WriteCommand(0x8D);	//设置充电泵
	OLED_WriteCommand(0x14);

	OLED_WriteCommand(0xAF);	//开启显示
		
	OLED_Clear();				//OLED清屏
}
